package P137_AdjustJVMParamsToAdvancePerformance;

/**
 * Desc:&emsp;&ensp;调整JVM参数以提高性能
 *
 * @author 李渊&emsp;liyuan7@yusys.com.cn
 * @version 1.0
 * @since V4.3&emsp;2022/5/20
 */
public class AdjustJVMParamsToAdvancePerformance {


    /**
     * 1.调整堆内存大小
     *
     *  在JVM中有两种内存：栈内存(Stack)和堆内存(Heap)，栈内存的特点
     * 是空间比较小，速度快，用来存放对象的引用及程序中的基本类型：而堆内存的特点是空间
     * 比较大，速度慢，一般对象都会在这里生成、使用和消亡。
     *  栈空间是由线程开辟，线程结束，栈空间由JVM回收，因此它的大小一般不会对
     * 性能有太大的影响，但是它会影响系统的稳定性，在超过栈内存的容量时，系统会报
     * StackOverflowError错误。可以通过"java -Xss<size>”设置栈内存大小来解决此类问题。
     *  堆内存的调整不能太随意，调整得太小，会导致FullGC频繁执行，轻则导致系统性能
     * 急速下降，重则导致系统根本无法使用；调整得太大，一则是浪费资源（当然，若设置了最
     * 小堆内存则可以避免此问题），二则是产生系统不稳定的情况，例如在32位的机器上设置超
     * 过1.8GB的内存就有可能产生莫名其妙的错误。设置初始化堆内存为1GB（也就是最小堆内
     * 存），最大堆内存为1.5GB可以用如下的参数：
     * java - Xmx1536m —Xms1024m
     *
     */

    /**
     * 2.调整堆内存中各区的比例
     *
     * JVM 的堆内存包括三部分： 新生区（ Young Generation Space) 、养老区（ Tenure
     * generation space) 、永久存储区（ Permanent Space ） ， 其中新生成的对象都在新生区， 它又分
     * 为伊甸区(Eden Space ） 、幸存0 区（ Survivor 0 Space) 和幸存1 区（ Survivor 1 Space ） ， 当
     * 在程序中使用了new 关键字时， 首先在伊甸区生成该对象， 如果伊甸区满了， 则用垃圾回收
     * 器先进行回收， 然后把剩余的对象移动到幸存区（ 0 区或1 区） ， 可如果幸存区也满了呢？ 垃
     * 圾回收器会再回收一次， 然后再把剩余的对象移动到养老区， 那要是养老区也满了呢？
     * 此时就会触发Full GC （ 这是一个非常危险的动作， JVM 会停止所有的执行， 所有系统资源都会
     * 让位给垃圾回收器） ， 会对所有的对象过滤一遍， 检查是否有可以回收的对象， 如果还是没
     * 有的话， 就抛出Out0fMemoryError 错误， 系统不干了！
     *  清楚了这个原理， 那我们就可以思考一
     * 下如何提升性能了： 若扩大新生区， 势必会减少养老区， 这就可能产生不稳定的情况， 一般
     * 情况下， 新生区和养老区的比例为1 ： 3 左右， 设置命令如下：
     * java -XX:NewSize=32m -XX:MaxNewSize=640m -XX:MaxPermSize=1280m XX:NewRatio=5
     * 该配置指定新生代初始化为32MB （ 也就是新生区最小内存为32M ） ， 最大不超过
     * 640MB ， 养老区最大不超过1280MB ， 新生区和养老区的比例为1:5。
     */

    /**
     * 3.变更GC垃圾回收策略
     *
     * Java 程序性能的最大障碍就是垃圾回收， 我们不知道它何时会发生， 也不知道它会执行
     * 多长时间， 但是我们可以想办法改变它对系统的影响， 比如启用并行垃圾回收、规定并行回
     * 收的线程数量等， 命令格式如下：
     * ava -XX:+Ügepara11e1GC -XX:Para11e1GCThreadg=20
     * 这里启用了并行垃圾收集机制， 并且定义了20 个收集线程（ 默认的收集线程等于CPU
     * 的数量） ， 这对多CPU 的系统是非常有帮助的， 可以大大减少垃圾回收对系统的影响， 提高
     * 系统性能。
     * 当然， 垃圾回收的策略还有很多属性可以修改， 比如UseSerialGC （ 启用串行GC ， 默认
     * 值） 、ScavengeBeforeFulIGC （ 新生代GC 优先于FuII GC 执行） 、UseConcMarkSweepGC （ 对
     * 老生代采用并发标记交换算法进行GC ） 等， 这些参数需要在系统中逐步调试。
     */

    /**
     * 4.更换JVM
     *
     * 如果所有的JVM 优化都不见效， 那只有使用最后一招了： 更换JVM ， 目前市面上比
     * 较流行的JVM 有三个产品： Java H0tSpot VM 、OracIe JRockit JVM 、IBM JVM ， 其中
     * HotSpot 是我们经常使用的， 稳定性、可靠性都不错： JRockit 则以效率著称， 性能是它
     * 的优势， 但在决定使用该JVM 之前一定要做好全面的系统测试， 它的某些行为可能会在
     * JRockit 上产生Bug ： IBM JVM 也比较稳定， 而且它在AIX 系统上的表现要远远好于其他
     * 操作系统。
     * JVM 的优化不能像程序优化一样， 找到Bug 就可以立刻解决， JVM 的优化一定是要循
     * 序渐进的， 参数设置不可激进， 特别是需要优化多个参数时， 一定要逐步实施， 确保每个优
     * 化步骤都达到了预期目标， 否则会对整个系统的稳定性产生较大的风险。需要提醒的是以上
     * 带有“ -xx ” 的JVM 参数可能是不健壮的， SIJN 也不推荐使用， 可能后续会在没有通知的
     * 情况下就不再支持它了， 但是它又非常好用， 这需要在系统升级、迁移时慎重考虑。
     */
}
